﻿using LxBasic;


namespace LxCore
{
    public abstract class ExtremeStatistic
    {
        public class Base : StatisticBase
        {

        }
        public class Min : Base
        {
            public override AccumulationDouble RunReport(UserMonitor userMonitor, bool isConsole = false)
            {
                double totalMin = double.MaxValue;
                if (isConsole)
                {

                }
                foreach ((FvInner z, ICellVarArr<double> zf, FvBound b, IFaceVarArr<double> bf) in getSelected(userMonitor, true, true))
                {
                    double localMin = double.MaxValue;
                    if (z != null)
                    {
                        if (zf != null)
                        {
                            MultiThreads.RunParallelTask((tid) =>
                            {
                                double tempMin = double.MaxValue;
                                (int i1, int endp1) = z.CellIdx.Split(tid);
                                for (; i1 < endp1; i1++)
                                {
                                    double d = zf.GetCellVar(i1);
                                    if (d < tempMin)
                                    {
                                        tempMin = d;
                                    }
                                }
                                ThreadsMath.KeepMin(ref localMin, tempMin);
                            });
                        }
                        if (isConsole)
                        {

                        }
                    }
                    else if (b != null)
                    {
                        if (bf != null)
                        {
                            MultiThreads.RunParallelTask((tid) =>
                            {
                                double tempMin = double.MaxValue;
                                (int i1, int endp1) = b.FaceIdx.Split(tid);
                                for (; i1 < endp1; i1++)
                                {
                                    double d = bf.GetFaceVar(i1);
                                    if (d < tempMin)
                                    {
                                        tempMin = d;
                                    }
                                }
                                ThreadsMath.KeepMin(ref localMin, tempMin);
                            });
                        }
                        if (isConsole)
                        {

                        }
                    }
                    if (localMin < totalMin)
                    {
                        totalMin = localMin;
                    }
                }
                if (isConsole)
                {
                    //输出
                }
                return totalMin == double.MaxValue ? AccumulationDouble.Empty : new AccumulationDouble(totalMin);
            }
        }
        public class Max : Base
        {
            public override AccumulationDouble RunReport(UserMonitor userMonitor, bool isConsole = false)
            {
                double totalMax = double.MinValue;
                if (isConsole)
                {

                }
                foreach ((FvInner z, ICellVarArr<double> zf, FvBound b, IFaceVarArr<double> bf) in getSelected(userMonitor, true, true))
                {
                    double localMax = double.MinValue;
                    if (z != null)
                    {
                        MultiThreads.RunParallelTask((tid) =>
                        {
                            double tempMax = double.MinValue;
                            (int i1, int endp1) = z.CellIdx.Split(tid);
                            for (; i1 < endp1; i1++)
                            {
                                double d = zf.GetCellVar(i1);
                                if (d > tempMax)
                                {
                                    tempMax = d;
                                }
                            }
                            ThreadsMath.KeepMax(ref localMax, tempMax);
                        });
                        if (isConsole)
                        {

                        }
                    }
                    else if (b != null)
                    {
                        MultiThreads.RunParallelTask((tid) =>
                        {
                            double tempMax = double.MinValue;
                            (int i1, int endp1) = b.FaceIdx.Split(tid);
                            for (; i1 < endp1; i1++)
                            {
                                double d = bf.GetFaceVar(i1);
                                if (d > tempMax)
                                {
                                    tempMax = d;
                                }
                            }
                            ThreadsMath.KeepMax(ref localMax, tempMax);
                        });
                        if (isConsole)
                        {

                        }
                    }
                    if (localMax > totalMax)
                    {
                        totalMax = localMax;
                    }
                }
                if (isConsole)
                {
                    //输出
                }
                return totalMax == double.MinValue ? AccumulationDouble.Empty : new AccumulationDouble(totalMax);
            }
        }
    }
    //public class MaxValueStatistic : StatisticBase
    //{

    //    public override void GlobalIni()
    //    {
    //        base.GlobalIni();
    //        GlobalResult = double.MinValue;
    //    }
    //    public override void LocalIni()
    //    {
    //        base.LocalIni();
    //        LocalResult = double.MinValue;
    //    }
    //    public override void LocalFinish()
    //    {
    //        if (LocalResult > GlobalResult)
    //        {
    //            GlobalResult = LocalResult;
    //        }
    //    }
    //    public override void StatisticCells(IIndexHost cellIdx, ICellVar<double> sf, ICellVar<double> assistant, ThreadInfo threadInfo)
    //    {
    //        double localMax = double.MinValue;
    //        (int i1, int endp1) = cellIdx.GetCellIdx().GetTaskIdx(threadInfo);
    //        for (; i1 < endp1; i1++)
    //        {
    //            double d = sf.GetCellValue(i1);
    //            if (d > localMax)
    //            {
    //                localMax = d;
    //            }
    //        }
    //        ThreadsMath.KeepMax(ref LocalResult, localMax);
    //    }
    //    public override void StatisticFaces(IIndexHost faceIdx, IFaceVar<double> sf, IFaceVar<double> assistant, ThreadInfo threadInfo)
    //    {
    //        double localMax = double.MinValue;
    //        (int i1, int endp1) = faceIdx.GetFaceIdx().GetTaskIdx(threadInfo);
    //        for (; i1 < endp1; i1++)
    //        {
    //            double d = sf.GetFaceValue(i1);
    //            if (d > localMax)
    //            {
    //                localMax = d;
    //            }
    //        }
    //        ThreadsMath.KeepMax(ref LocalResult, localMax);
    //    }


    //}
}
//public override void RunStatistic(bool IsConsole)
//{
//    InMonitor.CurrentResult = double.MinValue;
//    LocalResult = double.MinValue;
//    StatisticZoneThreads(IsConsole);
//}
//protected override void SortOutResult()
//{
//    if (LocalResult > InMonitor.CurrentResult)
//    {
//        InMonitor.CurrentResult = LocalResult;
//    }
//    LocalResult = double.MinValue;
//}
//protected override void StatisticZone(FvZone zone, IField<double> scalar, ThreadInfo threadInfo)
//{
//    double localMax = double.MinValue;
//    (int i1, int endp1) = zone.Inner.CellIdx.GetSeg(  threadInfo);
//    var sf = scalar.GetCellField(zone.Inner, this);
//    for (; i1 < endp1; i1++)
//    {
//        double d = sf.GetCellValue(i1);
//        if (d > localMax)
//        {
//            localMax = d;
//        }
//    }
//    ThreadsMath.KeepMax(ref LocalResult, localMax);
//}
//protected override void StatisticThread(FvZone zone, FvBound thread, IField<double> scalar, ThreadInfo threadInfo)
//{
//    double localMax = double.MinValue;
//    (int i1, int endp1) = thread.CellIdx.GetSeg(  threadInfo);
//    var sf = scalar.GetFaceField(thread, this);
//    for (; i1 < endp1; i1++)
//    {
//        double d = sf.GetFaceValue(i1);
//        if (d > localMax)
//        {
//            localMax = d;
//        }
//    }
//    ThreadsMath.KeepMax(ref LocalResult, localMax);
//}